package cn.com.hhrcw.web;

import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.params.EntryParam;
import cn.com.hhrcw.position.entity.RecruitmentPosition;
import cn.com.hhrcw.position.service.IRecruitmentPositionService;
import cn.com.hhrcw.service.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import io.swagger.annotations.Api;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static cn.com.hhrcw.utils.DateUtil.getLastMonths;

/**
 * @program: recruit-boot-parent
 * @description: 批量下载简历
 * @author: JD
 * @create: 2020-11-24 09:54
 **/
@RestController
@Slf4j
@RequestMapping("/admin/download/resume")
@Api(tags = "批量下载简历")
@Validated
public class DownloadResumeController {

    @Autowired
    private ICvResumeService resumeService;

    @Autowired
    private IFileService fileService;

    @Autowired
    private IPiInfoService piInfoService;

    @Autowired
    private IEnInfoService enInfoService;

    @Autowired
    private ICvUserEduInfoService eduInfoService;

    @Autowired
    private ICvWorkIntentionService workIntentionService;

    @Autowired
    IRecruitmentPositionService positionService;

    @Autowired
    private IEnContactsService enContactsService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    private IOpJobService opJobService;

    @Autowired
    private IFileDownloadService fileDownloadService;

    @Autowired
    private ISysBaseAPI sysBaseApi;

    /**
     * 人才库-人才
     *
     * @param params
     * @return
     */
    List<String> getUserListInfo(EntryParam params) {
        Map<String, Object> queryMap = new HashMap<>(16);
        if (StrUtil.isNotBlank(params.getJobName())) {
            List<RecruitmentPosition> positions = positionService.lambdaQuery()
                .select(RecruitmentPosition::getId)
                .like(RecruitmentPosition::getName, params.getJobName())
                .list();
            queryMap.put("positions", positions.stream().map(RecruitmentPosition::getId).toArray());
        }
        if (StrUtil.isNotBlank(params.getDataId())) {
            queryMap.put("deliveryId", params.getDataId().split(","));
        }
        queryMap.put("sysFrom", params.getSysFrom());
        queryMap.put("sex", params.getSex());
        queryMap.put("bsType", params.getBsType());
        queryMap.put("bsId", params.getSsId());
        queryMap.put("maritalStatus", params.getMaritalStatus());
        queryMap.put("state", null);
        int five = 5;
        if (params.getState() != null) {
            if (params.getState() == 0) {
                queryMap.put("state", new Integer[]{0, 1});
            } else if (params.getState() == five) {
                queryMap.put("state", new Integer[]{5, 9});
            } else {
                queryMap.put("state", new Integer[]{params.getState()});
            }
        }
        queryMap.put("name", params.getUserName());
        //            应聘时间范围 0 近三个月 1近半年
        queryMap.put("createTimeBegin", null);
        queryMap.put("createTimeEnd", null);
        Date now = new Date();
        if (params.getTimeState() != null && params.getTimeState() == 0) {
            queryMap.put("createTimeBegin", cn.hutool.core.date.DateUtil.offsetMonth(now, -3));
        } else if (params.getTimeState() != null && params.getTimeState() == 1) {
            queryMap.put("createTimeBegin", cn.hutool.core.date.DateUtil.offsetMonth(now, -6));
        }
        queryMap.put("createTimeEnd", now);
        //工作经验
        if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
            if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == 0) {
                queryMap.put("jobTimeBegin", null);
                queryMap.put("jobTimeEnd", null);
            } else {
                DateTime start = cn.hutool.core.date.DateUtil.offsetMonth(now, -(params.getMaxWorkYear() * 12));
                DateTime end = cn.hutool.core.date.DateUtil.offsetMonth(now, -(params.getMinWorkYear() * 12));
                queryMap.put("jobTimeBegin", start.toString(DatePattern.NORM_DATE_PATTERN));
                queryMap.put("jobTimeEnd", end.toString(DatePattern.NORM_DATE_PATTERN));
            }
        }
        //期望月薪
        if (params.getMinMoney() != null && params.getMaxMoney() != null) {
            queryMap.put("minMoney", params.getMinMoney());
            queryMap.put("maxMoney", params.getMaxMoney());
        }
        if (StrUtil.isNotBlank(params.getWorkIndustry())) {
            queryMap.put("workIndustry", params.getWorkIndustry() + ",");
        }
        //年龄
        if (params.getMinAge() != null) {
            String endBirthday = cn.com.hhrcw.utils.DateUtil.getYearFirst(params.getMinAge() - 1);
            queryMap.put("endBirthday", endBirthday);

        }
        if (params.getMaxAge() != null) {
            String beginBirthday = cn.com.hhrcw.utils.DateUtil.getYearFirst(params.getMaxAge());
            queryMap.put("beginBirthday", beginBirthday);
        }
        IPage<OpDeliveryHistory> opDeliveryHistoryPage = this.deliveryHistoryService.resumeTalentList(new Page(1, -1), queryMap);
        return CollUtil.map(opDeliveryHistoryPage.getRecords(), OpDeliveryHistory::getUserId, true);
    }

    /**
     * 专场人才
     *
     * @param params
     * @return
     */
    public List<String> getUserList(EntryParam params) {
        LambdaQueryWrapper<OpJob> jobLambdaQueryWrapper = new LambdaQueryWrapper<>();
        jobLambdaQueryWrapper.eq(OpJob::getDelFlag, false);

        if (StringUtils.isNotBlank(params.getSsId())) {
            jobLambdaQueryWrapper.eq(OpJob::getBsType, 1).eq(OpJob::getBsId, params.getSsId());
        }
        if (StringUtils.isNotBlank(params.getJobId())) {
            jobLambdaQueryWrapper.eq(OpJob::getId, params.getJobId());
        }
        if (StringUtils.isNotBlank(params.getJobName())) {
            jobLambdaQueryWrapper.like(OpJob::getJobName, params.getJobName());
        }
        if (StringUtils.isNotBlank(params.getRecruitType())) {
            jobLambdaQueryWrapper.like(OpJob::getRecruitType, params.getRecruitType());
        }
        if (StringUtils.isNotBlank(params.getComName())) {
            List<EnInfo> enInfos = enInfoService.lambdaQuery().like(EnInfo::getEnName, params.getComName()).eq(EnInfo::getDelFlag, false).list();
            if (CollectionUtils.isEmpty(enInfos)) {
                return new ArrayList<>();
            } else {
                List<String> comIds = new ArrayList<>();
                enInfos.forEach(e -> {
                    comIds.add(e.getId());
                });
                jobLambdaQueryWrapper.in(OpJob::getCompanyId, comIds);
            }

        }

        if (params.getBsType() != null) {
            jobLambdaQueryWrapper.eq(OpJob::getBsType, params.getBsType());
        }
        if (params.getSysFrom() != null) {
            jobLambdaQueryWrapper.eq(OpJob::getSysFrom, params.getSysFrom());
        }
        List<OpJob> jobs = opJobService.list(jobLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(jobs)) {
            List<String> jobIds = new ArrayList<>();
            jobs.forEach(e -> {
                jobIds.add(e.getId());
            });
            LambdaQueryWrapper<OpDeliveryHistory> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds);
            int b = 5;
            if (StringUtils.isNotBlank(params.getConName()) && params.getState() == b) {
                List<EnContacts> contacts = enContactsService.lambdaQuery().like(EnContacts::getUserName, params.getConName()).eq(EnContacts::getDelFlag, false).list();
                if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(contacts)) {
                    return new ArrayList<>();
                }
                List<String> conIds = new ArrayList<>();
                contacts.forEach(enContacts -> {
                    conIds.add(enContacts.getId());
                });
                List<OpEntryHistory> histories = entryHistoryService.lambdaQuery().in(OpEntryHistory::getContactId, conIds).eq(OpEntryHistory::getDelFlag, false).select(OpEntryHistory::getJobId, OpEntryHistory::getUserId).list();
                if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(histories)) {
                    return new ArrayList<>();
                }
                queryWrapper.and(query -> {
                    histories.forEach(e -> {
                        query.or(queryIn -> queryIn.eq(OpDeliveryHistory::getJobId, e.getJobId()).eq(OpDeliveryHistory::getUserId, e.getUserId()));
                    });
                    return query;
                });
            }
            int c = 4;
            if (StringUtils.isNotBlank(params.getConName()) && params.getState() == c) {
                List<EnContacts> contacts = enContactsService.lambdaQuery().like(EnContacts::getUserName, params.getConName()).eq(EnContacts::getDelFlag, false).list();
                if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(contacts)) {
                    return new ArrayList<>();
                }
                List<String> conIds = new ArrayList<>();
                contacts.forEach(enContacts -> {
                    conIds.add(enContacts.getId());
                });
                List<OpInterviewHistory> histories = interviewHistoryService.lambdaQuery().in(OpInterviewHistory::getContactId, conIds).eq(OpInterviewHistory::getDelFlag, false).select(OpInterviewHistory::getJobId, OpInterviewHistory::getUserId).list();
                if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(histories)) {
                    return new ArrayList<>();
                }
                queryWrapper.and(query -> {
                    histories.forEach(e -> {
                        query.or(queryIn -> queryIn.eq(OpDeliveryHistory::getJobId, e.getJobId()).eq(OpDeliveryHistory::getUserId, e.getUserId()));
                    });
                    return query;
                });
            }

            /**
             * 0 未阅读 1 已阅读  2 不合适 3 通过筛选 4  面试 5已发offer(已录用)6 已入职 7 被过滤
             */
            int d = 5;
            if (params.getState() != null) {
                if (params.getState() == 0) {
                    queryWrapper.in(OpDeliveryHistory::getState, new Integer[]{0, 1});
                } else if (params.getState() == d) {
                    queryWrapper.in(OpDeliveryHistory::getState, new Integer[]{5, 9});
                } else {
                    queryWrapper.eq(OpDeliveryHistory::getState, params.getState());
                }
            }

            if (StringUtils.isNotBlank(params.getUserName())) {
                LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
                infoQuery.like(PiInfo::getName, params.getUserName()).eq(PiInfo::getDelFlag, false);
                List<PiInfo> piInfoList = piInfoService.list(infoQuery);
                if (CollectionUtils.isEmpty(piInfoList)) {
                    return new ArrayList<>();
                } else {
                    List<String> userIds = new ArrayList<>();
                    piInfoList.forEach(e -> {
                        userIds.add(e.getUserId());
                    });
                    queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
                }
            }

            if (params.getEduLevel() != null) {
                //0 初中  1 高中 2 中专/中技 3 大专 4 本科 5 硕士 6 MBA/EMBA  7 博士
                LambdaQueryWrapper<CvUserEduInfo> eduQuery = new LambdaQueryWrapper<>();
                eduQuery.eq(CvUserEduInfo::getDelFlag, false).eq(CvUserEduInfo::getEduLevel, params.getEduLevel());
                List<CvUserEduInfo> eduInfos = eduInfoService.list(eduQuery);
                if (CollectionUtils.isEmpty(eduInfos)) {
                    return new ArrayList<>();
                } else {
                    List<String> userIds = new ArrayList<>();
                    eduInfos.forEach(e -> {
                        userIds.add(e.getUserId());
                    });
                    queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
                }
            }

            if (params.getMaritalStatus() != null) {
                LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
                infoQuery.ge(PiInfo::getMaritalStatus, params.getMaritalStatus());
                List<PiInfo> piInfoList = piInfoService.list(infoQuery);
                if (CollectionUtils.isEmpty(piInfoList)) {
                    return new ArrayList<>();
                } else {
                    List<String> userIds = new ArrayList<>();
                    piInfoList.forEach(e -> {
                        userIds.add(e.getUserId());
                    });
                    queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
                }
            }

            if (params.getSex() != null) {
                LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
                if (params.getSex() != 0) {
                    infoQuery.ge(PiInfo::getSex, params.getSex());
                    List<PiInfo> piInfoList = piInfoService.list(infoQuery);
                    if (CollectionUtils.isEmpty(piInfoList)) {
                        return new ArrayList<>();
                    } else {
                        List<String> userIds = new ArrayList<>();
                        piInfoList.forEach(e -> {
                            userIds.add(e.getUserId());
                        });
                        queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
                    }
                }
            }

            if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
                LambdaQueryWrapper<PiInfo> infoQuery = new LambdaQueryWrapper<>();
                int f = 999;
                if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == f) {

                } else if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == 0) {
                    infoQuery.isNull(PiInfo::getJobTime);
                } else {
                    String start = cn.com.hhrcw.utils.DateUtil.getYearFirst(params.getMaxWorkYear());
                    String end = cn.com.hhrcw.utils.DateUtil.getYearLast(params.getMinWorkYear());
                    infoQuery.ge(PiInfo::getJobTime, start).le(PiInfo::getJobTime, end);
                }
                List<PiInfo> piInfoList = piInfoService.list(infoQuery);
                if (CollectionUtils.isEmpty(piInfoList)) {
                    return new ArrayList<>();
                } else {
                    List<String> userIds = new ArrayList<>();
                    piInfoList.forEach(e -> {
                        userIds.add(e.getUserId());
                    });
                    queryWrapper.in(OpDeliveryHistory::getUserId, userIds);
                }
            }

            if (params.getTimeState() != null) {
                if (0 == params.getTimeState()) {
                    queryWrapper.ge(OpDeliveryHistory::getCreateTime, getLastMonths(3));
                } else if (1 == params.getTimeState()) {
                    queryWrapper.ge(OpDeliveryHistory::getCreateTime, getLastMonths(6));
                }
            }
            queryWrapper.eq(OpDeliveryHistory::getDelFlag, false).orderByDesc(OpDeliveryHistory::getCreateTime);
            List<OpDeliveryHistory> list = deliveryHistoryService.list(queryWrapper);
            return list.stream().map(OpDeliveryHistory::getId).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    public List<String> candidateList(EntryParam params) {
        QueryWrapper<OpDeliveryHistory> wrapper = Wrappers.query();
        if (StrUtil.isNotBlank(params.getJobName())) {
            wrapper.like("op_job.job_name", params.getJobName());
        }
        if (StrUtil.isNotBlank(params.getComName())) {
            wrapper.like("en_info.en_name", params.getComName());
        }
        if(StrUtil.isNotBlank(params.getRecruitType())){
            wrapper.eq("op_job.recruit_type", params.getRecruitType());
        }
        if (StrUtil.isNotBlank(params.getUserName())) {
            wrapper.like("pi_info.name", params.getUserName());
        }
        if (params.getBsType() != null) {
            wrapper.eq("op_job.bs_type", params.getBsType())
                .eq("op_job.sys_from", params.getSysFrom());
        } else if (params.getSysFrom() != null) {
            wrapper.eq("op_job.sys_from", params.getSysFrom());
        }
        if (params.getMinWorkYear() != null && params.getMaxWorkYear() != null) {
            int g = 999;
            if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == g) {

            } else if (params.getMinWorkYear() == 0 && params.getMaxWorkYear() == 0) {
                wrapper.isNull("pi_info.job_time");
            } else {
                String start = cn.com.hhrcw.utils.DateUtil.getYearFirst(params.getMaxWorkYear());
                String end = cn.com.hhrcw.utils.DateUtil.getYearLast(params.getMinWorkYear());
                wrapper.ge("pi_info.job_time", start).le("pi_info.job_time", end);
            }
        }
        if (params.getState() == 0) {
            wrapper.in("op_delivery_history.state", 0, 1);
        } else {
            wrapper.eq("op_delivery_history.state", params.getState());
        }
        if (params.getTimeState() != null) {
            if (params.getTimeState() == 0) {
                wrapper.ge("op_delivery_history.create_time", getLastMonths(3));
            } else if (params.getTimeState() == 1) {
                wrapper.ge("op_delivery_history.create_time", getLastMonths(6));
            }
        }
        if(params.getApplyBeginTime() != null && params.getApplyEndTime() != null) {
            wrapper.between("op_delivery_history.create_time", params.getApplyBeginTime(), params.getApplyEndTime()).eq("op_job.del_flag", false);
        }
        IPage page = params.page();
        page.setSize(-1);
        Page<OpDeliveryHistory> opDeliveryHistoryPage = this.deliveryHistoryService.candidateList(page, wrapper);
        List<OpDeliveryHistory> records = opDeliveryHistoryPage.getRecords();
        return records.stream().map(OpDeliveryHistory::getId).collect(Collectors.toList());
    }

    @GetMapping("/zip")
    public Result downloadZip(String exportType, String userId, EntryParam params) {
        FileDownload download = new FileDownload();
        download.setCreateTime(new Date());
        download.setState("EXEC");
        download.setFrom(params.getFrom());
        fileDownloadService.save(download);
        //异步导出
        ThreadUtil.execAsync(() -> this.downZip(exportType, userId, params, download.getId()));
        return Result.ok();
    }

    /**
     * 批量简历zip
     *
     * @param userId     userId
     * @param exportType candidate 候选人导出
     */
    @SneakyThrows
    public void downZip(String exportType, String userId, EntryParam params, Long downloadId) {
        Set<String> zipEntryNameSet = new HashSet<>();
        LambdaUpdateChainWrapper<FileDownload> wrapper = fileDownloadService.lambdaUpdate()
            .eq(FileDownload::getId, downloadId);
        ZipSecureFile.setMinInflateRatio(0);
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ZipOutputStream zipOutputStream = new ZipOutputStream(bos)) {
            String candidate = "candidate";
            //专场 候选人选择导出
            if (StrUtil.isNotBlank(params.getDataId())) {
                String[] split = params.getDataId().split(",");
                for (String id : split) {
                    byte[] bytes = this.resumeService.getResumeInfo(id, null);
                    OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                    CvResume resume = this.resumeService.getById(history.getResumeId());
                    PiInfo info = this.piInfoService.getById(history.getUserId());
                    String jobName = opJobService.getJobName(history.getJobId());
                    //String phone = info.getPhone();
                    //String name = /*info.getName() + "_" + phone + "/" + */resume.getResumeName() + "_" + history.getId() + ".docx";
                    String name = jobName +"_"+info.getName() + ".docx";
                    if(!zipEntryNameSet.contains(name)){
                        ZipEntry zipEntry = new ZipEntry(name);
                        zipOutputStream.putNextEntry(zipEntry);
                        zipOutputStream.write(bytes);
                        zipOutputStream.flush();
                        zipEntryNameSet.add(name);
                    }

                }
            }
            //专场搜索导出
            else if (StrUtil.isNotBlank(params.getSsId())) {
                List<String> list = this.getUserList(params);
                for (String id : list) {
                    byte[] bytes = this.resumeService.getResumeInfo(id, null);
                    if (bytes == null) {
                        continue;
                    }
                    OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                    //CvResume resume = this.resumeService.getById(history.getResumeId());
                    PiInfo info = this.piInfoService.getById(history.getUserId());
                    String jobName = opJobService.getJobName(history.getJobId());
                    //String phone = info.getPhone();
                    //String name = /*info.getName() + "_" + phone + "/" +*/ resume.getResumeName() + "_" + history.getId() + ".docx";
                    String name = jobName +"_"+info.getName() + ".docx";
                    if(!zipEntryNameSet.contains(name)){
                        ZipEntry zipEntry = new ZipEntry(name);
                        zipOutputStream.putNextEntry(zipEntry);
                        zipOutputStream.write(bytes);
                        zipOutputStream.flush();
                        zipEntryNameSet.add(name);
                    }

                }
            }
            //候选人搜索导出
            else if (StrUtil.equals(candidate, exportType)) {
                List<String> list = this.candidateList(params);
                for (String id : list) {
                    byte[] bytes = this.resumeService.getResumeInfo(id, null);
                    if (bytes == null) {
                        continue;
                    }
                    OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                    //CvResume resume = this.resumeService.getById(history.getResumeId());
                    PiInfo info = this.piInfoService.getById(history.getUserId());
                    String jobName = opJobService.getJobName(history.getJobId());
                    //String phone = info.getPhone();
                    //String name = /*info.getName() + "_" + phone + "/" + */resume.getResumeName() + "_" + history.getId() + ".docx";
                    String name = jobName +"_"+info.getName() + ".docx";
                    if(!zipEntryNameSet.contains(name)){
                        ZipEntry zipEntry = new ZipEntry(name);
                        zipOutputStream.putNextEntry(zipEntry);
                        zipOutputStream.write(bytes);
                        zipOutputStream.flush();
                        zipEntryNameSet.add(name);
                    }
                }
            }
            //人才库搜索导出
            else if (StrUtil.isBlank(userId)) {
                List<String> list = this.getUserListInfo(params);
                for (String id : list) {
                    List<byte[]> byteList = this.resumeService.getMultipleResumeInfo(null, id);
                    if (CollUtil.isEmpty(byteList)) {
                        continue;
                    }
                    PiInfo info = this.piInfoService.getById(id);
                    for (byte[] bytes : byteList) {
                        String phone = info.getPhone();
                        String name = new String(ArrayUtil.sub(bytes, 0, 512));
                        ZipEntry zipEntry = new ZipEntry(info.getName() + "_" + phone + "/" + name);
                        zipOutputStream.putNextEntry(zipEntry);
                        zipOutputStream.write(ArrayUtil.sub(bytes, 512, bytes.length));
                        zipOutputStream.flush();
                    }
                }

            }
            //人才库选择导出
            else if (StrUtil.isNotBlank(userId)) {
                String[] split = userId.split(",");
                for (String id : split) {
                    List<byte[]> byteList = this.resumeService.getMultipleResumeInfo(null, id);
                    PiInfo info = this.piInfoService.getById(id);
                    for (byte[] bytes : byteList) {
                        String name = new String(ArrayUtil.sub(bytes, 0, 512));
                        ZipEntry zipEntry = new ZipEntry(info.getName() + "_" + info.getPhone() + "/" + name);
                        zipOutputStream.putNextEntry(zipEntry);
                        zipOutputStream.write(ArrayUtil.sub(bytes, 512, bytes.length));
                        zipOutputStream.flush();
                    }
                }
            }
            zipOutputStream.finish();
            Map upload = (Map) sysBaseApi.uploadToLocal(bos.toByteArray(), "public/zip", "简历.zip", -11, true);
            wrapper.set(FileDownload::getUrl, upload.get("url"))
                .set(FileDownload::getState, "FINISHED")
                .set(FileDownload::getFinishTime, new Date())
                .update();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            wrapper.set(FileDownload::getState, "FAIL")
                .update();
        }
    }

    @SneakyThrows
    @GetMapping("/byUser")
    public void downloadResume(String[] users, String[] deliveries, HttpServletResponse response) {
        // 指明response的返回对象是文件流
        response.setContentType("application/octet-stream");
        String downloadName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "简历";
        // 设置在下载框默认显示的文件名
        response.setHeader("Content-Disposition", "attachment;filename=" + downloadName + ".zip");
        ZipSecureFile.setMinInflateRatio(0);
        ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
        if (ArrayUtil.isNotEmpty(deliveries)) {
            for (String id : deliveries) {
                byte[] bytes = resumeService.getResumeInfo(id, null);
                if (bytes == null) {
                    continue;
                }
                OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                CvResume resume = this.resumeService.getById(history.getResumeId());
                PiInfo info = this.piInfoService.getById(history.getUserId());
                String phone = info.getPhone();
                String name = info.getName() + "_" + phone + "/" + resume.getResumeName() + ".docx";
                ZipEntry zipEntry = new ZipEntry(name);
                zipOutputStream.putNextEntry(zipEntry);
                zipOutputStream.write(bytes);
                zipOutputStream.flush();
            }
        } else if (ArrayUtil.isNotEmpty(users)) {
            for (String id : users) {
                List<byte[]> bytes = resumeService.getMultipleResumeInfo(null, id);
                if (CollUtil.isEmpty(bytes)) {
                    continue;
                }
                PiInfo info = this.piInfoService.getById(id);
                String phone = info.getPhone();
                for (byte[] aByte : bytes) {
                    String name = StrUtil.str(ArrayUtil.sub(aByte, 0, 512), StandardCharsets.UTF_8);
                    ZipEntry zipEntry = new ZipEntry(info.getName() + "_" + phone + "/" + name);
                    zipOutputStream.putNextEntry(zipEntry);
                    zipOutputStream.write(ArrayUtil.sub(aByte, 512, aByte.length));
                    zipOutputStream.flush();
                }
            }
        }
        zipOutputStream.finish();
        zipOutputStream.close();
    }

    @GetMapping("/avatar")
    public Result downloadAvatar(String exportType, String userId, EntryParam params) {
        FileDownload download = new FileDownload();
        download.setCreateTime(new Date());
        download.setState("EXEC");
        download.setFrom(params.getFrom());
        fileDownloadService.save(download);
        //异步导出
        ThreadUtil.execAsync(() -> this.downAvatar(exportType, userId, params, download.getId()));
        return Result.ok();
    }

    /**
     * 批量简历zip
     *
     * @param userId     userId
     */
    @SneakyThrows
    public void downAvatar(String exportType, String userId, EntryParam params, Long downloadId) {
        Set<String> zipEntryNameSet = new HashSet<>();
        LambdaUpdateChainWrapper<FileDownload> wrapper = fileDownloadService.lambdaUpdate()
                .eq(FileDownload::getId, downloadId);
        ZipSecureFile.setMinInflateRatio(0);
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ZipOutputStream zipOutputStream = new ZipOutputStream(bos)) {

            String candidate = "candidate";
            //专场 候选人选择导出
            if (StrUtil.isNotBlank(params.getDataId())) {
                String[] split = params.getDataId().split(",");
                for (String id : split) {
                    OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                    PiInfo info = this.piInfoService.getById(history.getUserId());
                    String photoId = info.getPhotoId();
                    if(StringUtils.isNotBlank(photoId)&&!StringUtils.equals(photoId,"defaultPic")){
                        File f = fileService.getById(photoId);
                        if(f==null||StringUtils.isBlank(f.getFilePath())){
                            continue;
                        }
                        String url = f.getFilePath();
                        String suffix = url.substring(url.lastIndexOf("."));
                        java.io.File file = new java.io.File(url);
                        byte[] bytes = new byte[0];
                        if(file.exists()){
                            bytes = FileUtil.readBytes(file);
                        }

                        String name = info.getName()+suffix;
                        if (!zipEntryNameSet.contains(name)) {
                            ZipEntry zipEntry = new ZipEntry(name);
                            zipOutputStream.putNextEntry(zipEntry);
                            zipOutputStream.write(bytes);
                            zipOutputStream.flush();
                            zipEntryNameSet.add(name);
                        }
                    }
                }
            }
            //专场搜索导出
            else if (StrUtil.isNotBlank(params.getSsId())) {
                List<String> list = this.getUserList(params);
                for (String id : list) {
                    OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                    PiInfo info = this.piInfoService.getById(history.getUserId());
                    String photoId = info.getPhotoId();
                    if(StringUtils.isNotBlank(photoId)&&!StringUtils.equals(photoId,"defaultPic")){
                        File f = fileService.getById(photoId);
                        if(f==null||StringUtils.isBlank(f.getFilePath())){
                            continue;
                        }
                        String url = f.getFilePath();
                        String suffix = url.substring(url.lastIndexOf("."));
                        java.io.File file = new java.io.File(url);
                        byte[] bytes = new byte[0];
                        if(file.exists()){
                            bytes = FileUtil.readBytes(file);
                        }

                        String name = info.getName()+suffix;
                        if (!zipEntryNameSet.contains(name)) {
                            ZipEntry zipEntry = new ZipEntry(name);
                            zipOutputStream.putNextEntry(zipEntry);
                            zipOutputStream.write(bytes);
                            zipOutputStream.flush();
                            zipEntryNameSet.add(name);
                        }
                    }
                }
            }
            //候选人搜索导出
            else if (StrUtil.equals(candidate, exportType)) {
                List<String> list = this.candidateList(params);
                for (String id : list) {
                    OpDeliveryHistory history = this.deliveryHistoryService.getById(id);
                    PiInfo info = this.piInfoService.getById(history.getUserId());
                    String photoId = info.getPhotoId();
                    if(StringUtils.isNotBlank(photoId)&&!StringUtils.equals(photoId,"defaultPic")){
                        File f = fileService.getById(photoId);
                        if(f==null||StringUtils.isBlank(f.getFilePath())){
                            continue;
                        }
                        String url = f.getFilePath();
                        String suffix = url.substring(url.lastIndexOf("."));
                        java.io.File file = new java.io.File(url);
                        byte[] bytes = new byte[0];
                        if(file.exists()){
                            bytes = FileUtil.readBytes(file);
                        }

                        String name = info.getName()+suffix;
                        if (!zipEntryNameSet.contains(name)) {
                            ZipEntry zipEntry = new ZipEntry(name);
                            zipOutputStream.putNextEntry(zipEntry);
                            zipOutputStream.write(bytes);
                            zipOutputStream.flush();
                            zipEntryNameSet.add(name);
                        }
                    }
                }
            }
            //人才库搜索导出
            else if (StrUtil.isBlank(userId)) {
                List<String> list = this.getUserListInfo(params);
                for (String id : list) {
                    PiInfo info = this.piInfoService.getById(id);
                    String photoId = info.getPhotoId();
                    if(StringUtils.isNotBlank(photoId)&&!StringUtils.equals(photoId,"defaultPic")){
                        File f = fileService.getById(photoId);
                        if(f==null||StringUtils.isBlank(f.getFilePath())){
                            continue;
                        }
                        String url = f.getFilePath();
                        String suffix = url.substring(url.lastIndexOf("."));
                        java.io.File file = new java.io.File(url);
                        byte[] bytes = new byte[0];
                        if(file.exists()){
                            bytes = FileUtil.readBytes(file);
                        }

                        String name = info.getName()+suffix;
                        if (!zipEntryNameSet.contains(name)) {
                            ZipEntry zipEntry = new ZipEntry(name);
                            zipOutputStream.putNextEntry(zipEntry);
                            zipOutputStream.write(bytes);
                            zipOutputStream.flush();
                            zipEntryNameSet.add(name);
                        }
                    }
                }

            }
            //人才库选择导出
            else if (StrUtil.isNotBlank(userId)) {
                String[] split = userId.split(",");
                for (String id : split) {
                    PiInfo info = this.piInfoService.getById(id);
                    String photoId = info.getPhotoId();
                    if(StringUtils.isNotBlank(photoId)&&!StringUtils.equals(photoId,"defaultPic")){
                        File f = fileService.getById(photoId);
                        if(f==null||StringUtils.isBlank(f.getFilePath())){
                            continue;
                        }
                        String url = f.getFilePath();
                        String suffix = url.substring(url.lastIndexOf("."));
                        java.io.File file = new java.io.File(url);
                        byte[] bytes = new byte[0];
                        if(file.exists()){
                            bytes = FileUtil.readBytes(file);
                        }

                        String name = info.getName()+suffix;
                        if (!zipEntryNameSet.contains(name)) {
                            ZipEntry zipEntry = new ZipEntry(name);
                            zipOutputStream.putNextEntry(zipEntry);
                            zipOutputStream.write(bytes);
                            zipOutputStream.flush();
                            zipEntryNameSet.add(name);
                        }
                    }
                }
            }
            zipOutputStream.finish();
            Map upload = (Map) sysBaseApi.uploadToLocal(bos.toByteArray(), "public/zip", "头像.zip", -11, true);
            wrapper.set(FileDownload::getUrl, upload.get("url"))
                    .set(FileDownload::getState, "FINISHED")
                    .set(FileDownload::getFinishTime, new Date())
                    .update();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            wrapper.set(FileDownload::getState, "FAIL")
                    .update();
        }
    }
}
